/*
 * Copyright (C) Pietro Pilolli 2010 <pilolli.pietro@gmail.com>
 * 
 * Curtain is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Curtain is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <gtk/gtk.h>
#include <stdlib.h>

#include <cairo.h>


/* Grab pointer. */
void grab_pointer (GtkWidget *win, GdkEventMask eventmask)
{
  GdkGrabStatus result;
  gdk_error_trap_push ();    
  result = gdk_pointer_grab (win->window, FALSE,
			     eventmask, 0,
			     NULL,
			     GDK_CURRENT_TIME);

  gdk_flush ();
  if (gdk_error_trap_pop ())
    {
      g_printerr ("Grab pointer error\n");
    }
   
  switch (result)
    {
    case GDK_GRAB_SUCCESS:
      break;
    case GDK_GRAB_ALREADY_GRABBED:
      g_printerr ("Grab Pointer failed: AlreadyGrabbed\n");
      break;
    case GDK_GRAB_INVALID_TIME:
      g_printerr ("Grab Pointer failed: GrabInvalidTime\n");
      break;
    case GDK_GRAB_NOT_VIEWABLE:
      g_printerr ("Grab Pointer failed: GrabNotViewable\n");
      break;
    case GDK_GRAB_FROZEN:
      g_printerr ("Grab Pointer failed: GrabFrozen\n");
      break;
    default:
      g_printerr ("Grab Pointer failed: Unknown error\n");
    }

}


/* Ungrab pointer. */
void ungrab_pointer (GdkDisplay *display, GtkWidget *win)
{
  gdk_error_trap_push ();
  gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME);
  gdk_flush ();
  if (gdk_error_trap_pop ())
    {
      /* this probably means the device table is outdated,
	 e.g. this device doesn't exist anymore. 
      */
      g_printerr("Ungrab pointer device error\n");
    }
}


/* Set the cairo surface color to the RGBA string. */
void cairo_set_source_color_from_string ( cairo_t *cr, gchar *color)
{
  if (cr)
    {
      gint r,g,b,a;
      sscanf (color, "%02X%02X%02X%02X", &r, &g, &b, &a);
      cairo_set_source_rgba (cr,
                             ((gdouble) r) / 256,
                             ((gdouble) g) / 256,
                             ((gdouble) b) / 256,
                             ((gdouble) a) / 256);
    }
}


/* Scale the surface with the width and height requested */
cairo_surface_t *
scale_surface    (cairo_surface_t *surface,
                  gdouble width,
		  gdouble height)
{
  gdouble old_width = cairo_image_surface_get_width (surface);
  gdouble old_height = cairo_image_surface_get_height (surface);
	  
  cairo_surface_t *new_surface = cairo_surface_create_similar (surface, CAIRO_CONTENT_COLOR_ALPHA, width, height);
  cairo_t *cr = cairo_create (new_surface);

  /* Scale *before* setting the source surface (1) */
  cairo_scale (cr, (width / old_width), (height / old_height));
  cairo_set_source_surface (cr, surface, 0, 0);

  /* To avoid getting the edge pixels blended with 0 alpha, which would 
   * occur with the default EXTEND_NONE. Use EXTEND_PAD for 1.2 or newer (2)
   */
  cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REFLECT); 

  /* Replace the destination with the source instead of overlaying */
  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);

  /* Do the actual drawing */
  cairo_paint (cr);
   
  cairo_destroy (cr);

  return new_surface;
}


